package com.zz.zjc.service;

import com.alibaba.fastjson.JSONObject;
import com.zz.zjc.model.Player;
import com.zz.zjc.model.User;
import com.zz.zjc.util.NumberUtil;
import com.zz.zjc.util.SpringContextUtil;
import net.sourceforge.pinyin4j.PinyinHelper;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;

@ServerEndpoint("/webSocket/{sid}")
@Component
public class WebSocketServer {


    static PhrasesService phrasesService = null;
    static UserService userService = null;


    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static AtomicInteger onlineNum = new AtomicInteger();

    //concurrent包的线程安全Set，用来存放每个客户端对应的WebSocketServer对象。
    private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();
    private static ConcurrentHashMap<String, Player> playPools = new ConcurrentHashMap<>();
    private static String lastChengYu = null;

    //发送消息
    public void sendMessage(Session session, String message) throws IOException {
        if (session != null) {
            synchronized (session) {
                System.out.println("发送数据：" + message);
                session.getBasicRemote().sendText(message);
            }
        }
    }

    //给指定用户发送信息
    public void sendInfo(String id, String message) {
        Session session = sessionPools.get(id);
        try {
            sendMessage(session, message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void loginOut(String id) {
        Session session = sessionPools.get(id);
        if (session != null) {
            try {
                sendMessage(session, getJsonStr("msg", "xitong", "<span style= \"color:#0000FF;\">【你的账号在其他地方登录】</span>"));
                session.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    public void sendInfoAll(String message) {
        for (Session session : sessionPools.values()) {
            try {
                sendMessage(session, message);
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
        }
    }

    //建立连接成功调用
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "sid") String sid) {
        //先判断 用户真实  过滤假用户
        if (userService == null) {
            userService = (UserService) SpringContextUtil.getBean("userService");
        }
        if(onlineNum.get()>=200){
            try {
                sendMessage(session, getJsonStr("msg", "xitong", "<span style= \"color:#0000FF;\">【当前人数过多，请稍后再试】</span>"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        User user = userService.get(Integer.parseInt(sid));
        if (user != null) {
            loginOut(sid);
            sessionPools.put(sid, session);
            addOnlineCount();
            System.out.println(sid + "加入webSocket！当前人数为" + onlineNum);
            Player player = new Player();
            player.setId(sid);
            player.setName(user.getName());
            player.setHead(user.getHead());
            playPools.put(sid, player);
            sendInfoAll(getJsonStr("onlineNum", "xitong", playPools));
            sendInfo(sid, getJsonStr("login", "xitong", "登录成功"));
            sendInfoAll(getJsonStr("msg", "xitong", "欢迎<span style= \"color:#0000FF;\">【" + user.getName() + "】</span>加入"));
        } else {
            try {
                sendMessage(session, getJsonStr("msg", "xitong", "<span style= \"color:#0000FF;\">【你是个假用户】</span>"));
                session.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


       /* try {
            sendMessage(session, getJsonStr("onlineNum",  "", playPools));
        } catch (IOException e) {
            e.printStackTrace();
        }
*/
    }

    //关闭连接时调用
    @OnClose
    public void onClose(@PathParam(value = "sid") String sid) {
        sessionPools.remove(sid);
        playPools.remove(sid);
        subOnlineCount();
        System.out.println(sid + "断开webSocket连接！当前人数为" + onlineNum);
        User user = userService.get(Integer.parseInt(sid));
        if(user!=null){
            sendInfoAll(getJsonStr("msg", "xitong", "<span style= \"color:#0000FF;\">【" + user.getName() + "】</span> 离开了。"));
        }
        sendInfoAll(getJsonStr("onlineNum", "", playPools));
    }

    //收到客户端信息
    @OnMessage
    public void onMessage(String dataJson) throws IOException {
        System.out.println("收到数据：" + dataJson);

        try {
            JSONObject data = JSONObject.parseObject(dataJson);
            String sid = data.getString("sid");
            String type = data.getString("type");
            if ("login".equals(type)) {
                //注册
               /* JSONObject user = data.getJSONObject("data");
                String name = user.getString("name");
                String head = user.getString("head");
                Player player = new Player();
                player.setId(sid);
                player.setName(name);
                player.setHead(head);
                playPools.put(sid, player);
                sendInfoAll(getJsonStr("onlineNum", "xitong", playPools));
                sendInfo(sid, getJsonStr("login", "xitong", "登录成功"));
                sendInfoAll(getJsonStr("msg", "xitong", "欢迎<span style= \"color:#0000FF;\">【" + name + "】</span>加入到游戏"));*/
            } else if ("msg".equals(type)) {
                String msg = data.getString("data");
                if (Pattern.matches("^GM:.*", msg)) {
                    msg = msg.replaceAll("GM:", "");
                    sendInfoAll(getJsonStr("che", "xitong", msg));
                } else {
                    sendInfoAll(getJsonStr("msg", sid, msg));
                }
            } else if ("cyjl".equals(type)) {
                Player player = playPools.get(sid);
                String msg = data.getString("data");
                sendInfoAll(getJsonStr("msg", sid, msg));
                if (Pattern.matches("^成语接龙.*", msg) || Pattern.matches("^我先来.*", msg) || Pattern.matches("^你先来.*", msg)) {
                    msg = msg.replaceAll("成语接龙:", "");
                    msg = msg.replaceAll("成语接龙", "");
                    msg = msg.replaceAll("我先来:", "");
                    msg = msg.replaceAll("我先来", "");
                    msg = msg.replaceAll("你先来", "");
                    lastChengYu = null;
                    cyjl(player.getName(), msg.trim().length() == 0 ? null : msg);
                } else if (Pattern.matches("^提示.*", msg)) {
                    if (lastChengYu != null) {
                        String[] pinyin2 = PinyinHelper.toHanyuPinyinStringArray(lastChengYu.substring(lastChengYu.length() - 1).charAt(0));
                        sendInfoAll(getJsonStr("msg", "xitong", "<span style= \"color:#0000FF;\">@" + player.getName() + "</span> 拼音提示：<span style= \"color:#0000FF;\">【" + Arrays.toString(pinyin2) + "】</span> "));
                    }
                } else {
                    cyjl(player.getName(), msg);
                }
            } else if ("che".equals(type)) {
                String msg = data.getString("data");
                sendInfoAll(getJsonStr("che", sid, msg));
            } else if ("dice".equals(type)) {
                String msg = "<ul class=\"box\"><li>"+NumberUtil.makeRandomDice()+"</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul>";
                sendInfoAll(getJsonStr("che", sid, msg));
            } else if ("base64".equals(type)) {
                String msg = data.getString("data");
                sendInfoAll(getJsonStr("base64", sid, msg));
            }
        } catch (Exception e) {
            e.printStackTrace();

        }
        //
        //

    }

    //错误时调用
    @OnError
    public void onError(Session session, Throwable throwable) {
        System.out.println("发生错误");
        throwable.printStackTrace();
    }

    public static void addOnlineCount() {
        onlineNum.incrementAndGet();
    }

    public static void subOnlineCount() {
        onlineNum.decrementAndGet();
    }

    public static String getJsonStr(String type, String sid, Object data) {
        JSONObject json = new JSONObject();
        json.put("type", type);
        json.put("sid", sid);
        json.put("data", data);
        return json.toString();
    }

    private void cyjl(String name, String text) {
        if (phrasesService == null) {
            phrasesService = (PhrasesService) SpringContextUtil.getBean("phrasesService");
        }
        if (text != null && text.trim().length() > 0) {
            if (phrasesService.check(text) == 0) {
                sendInfoAll(getJsonStr("msg", "xitong", "<span style= \"color:#0000FF;\">@" + name + "</span> <span style= \"color:#0000FF;\">【" + text + "】</span>不是成语哦"));
            } else {
                text = text.trim();
                if (lastChengYu != null) {
                    //判断接龙对不对
                    String[] pinyin = PinyinHelper.toHanyuPinyinStringArray(text.substring(0, 1).charAt(0));
                    String[] pinyin2 = PinyinHelper.toHanyuPinyinStringArray(lastChengYu.substring(lastChengYu.length() - 1).charAt(0));
                    HashSet<String> set = new HashSet<>(Arrays.asList(pinyin));
                    set.retainAll(Arrays.asList(pinyin2));
                    if (set.size() == 0) {
                        //接龙错误
                        sendInfoAll(getJsonStr("msg", "xitong", "<span style= \"color:#0000FF;\">@" + name + "</span> 没有接上哟，我们正在接：<span style= \"color:#0000FF;\">【" + lastChengYu + "】</span> "));
                        return;
                    }
                    if (text.substring(0, 1).equals(lastChengYu.substring(lastChengYu.length() - 1))) {
                        sendInfoAll(getJsonStr("msg", "xitong", "<span style= \"color:#0000FF;\">@" + name + "</span> 真棒！居然是同字。"));
                    }
                }

                String text_ = text.substring(text.length() - 1);
                String[] pinyin = PinyinHelper.toHanyuPinyinStringArray(text_.charAt(0)); // str.charAt(0) 第一个汉字
                String str = null;

                for (int i = 0; i < pinyin.length; i++) {
                    System.out.println("接龙：" + text_ + "  " + pinyin[i]);
                    str = phrasesService.find(text_, pinyin[i]);
                    if (str != null) {
                        continue;
                    }
                }
                if (str != null) {
                    lastChengYu = str;
                    sendInfoAll(getJsonStr("msg", "xitong", "<span style= \"color:#0000FF;\">@" + name + "</span> 我接<span style= \"color:#0000FF;\">【" + str + "】</span>"));
                } else {
                    sendInfoAll(getJsonStr("msg", "xitong", "<span style= \"color:#0000FF;\">@" + name + "</span> <span style= \"color:#0000FF;\">【" + text + "】</span> 太难了，我投降！"));
                }

            }
        } else {
            if (lastChengYu == null) {
                lastChengYu = phrasesService.rand();
                sendInfoAll(getJsonStr("msg", "xitong", "<span style= \"color:#0000FF;\">@" + name + "</span> 我先来 <span style= \"color:#0000FF;\">【" + lastChengYu + "】</span>"));

            }
        }

    }


}